package batch_kube

import (
	"bufio"
	"context"
	"fmt"
	"os"
	"strconv"
	"sync"

	"golang_study/internal/util"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
)

type PodInfo struct {
	Namespace string
	Name      string
	Status    string
}

type delPodFun func(string, string, *kubernetes.Clientset)

func GetPods(ns string, clientSet *kubernetes.Clientset) []PodInfo {
	var podInfos []PodInfo
	allPod := make([]string, 0)
	allNamespace := make([]string, 0)
	allStatus := make([]string, 0)

	c, _ := clientSet.CoreV1().Pods(ns).List(context.Background(), metav1.ListOptions{})

	fmt.Printf("Pod Lists: (No, Namespace, Name, Status)\n")
	for _, item := range c.Items {
		podInfos = append(podInfos, PodInfo{Name: item.Name, Namespace: item.Namespace, Status: string(item.Status.Phase)})
	}

	for _, podInfo := range podInfos {
		allPod = append(allPod, podInfo.Name)
		allNamespace = append(allNamespace, podInfo.Namespace)
		allStatus = append(allStatus, podInfo.Status)
	}

	for n, podInfo := range podInfos {
		podFormat := "Pods: %-3d %-" + strconv.Itoa(util.CalculateMaxLength(allPod)) + "s %-" + strconv.Itoa(util.CalculateMaxLength(allNamespace)) + "s %-" + strconv.Itoa(util.CalculateMaxLength(allStatus)) + "s\n"
		fmt.Printf(podFormat, n+1, podInfo.Name, podInfo.Namespace, podInfo.Status)
	}
	fmt.Println()

	return podInfos
}

func delPod(ns string, name string, clientSet *kubernetes.Clientset) {
	err := clientSet.CoreV1().Pods(ns).Delete(context.Background(), name, metav1.DeleteOptions{})

	if err != nil {
		fmt.Printf("Error deleting pod, %s", err)
	}
}

func DelPods(ns string, names []string, interactive bool, clientSet *kubernetes.Clientset) {
	if interactive {
		interactiveDelPods(ns, clientSet)
	} else {
		if names != nil {
			for _, n := range names {
				delPod(ns, n, clientSet)
			}
		} else {
			util.IsBatch(ns)

			podInfos := GetPods(ns, clientSet)
			for _, p := range podInfos {
				delPod(p.Namespace, p.Name, clientSet)
			}
		}
	}
}

func interactiveDelPods(ns string, clientSet *kubernetes.Clientset) {
	podInfoChan := make(chan []PodInfo)
	var wg sync.WaitGroup

	go func(podInfoChan chan []PodInfo) {
		for {
			wg.Add(1)
			podInfo := GetPods(ns, clientSet)
			podInfoChan <- podInfo
			wg.Wait()
		}
	}(podInfoChan)

	for {
		podInfo := <-podInfoChan
		fmt.Printf("Which one do you want to delete? [No|No1,No2..|all] ")

		reader := bufio.NewReader(os.Stdin)
		input, err := reader.ReadString('\n')
		if err != nil {
			fmt.Printf("Fail is reason that, %s\n", err)
		}

		nsArgs := util.InitArgs(input)
		if nsArgs == nil {
			fmt.Printf("Missing value for input.\n")
		} else if len(podInfo) < util.FindMaxNumber(nsArgs) {
			fmt.Printf("Number is invalid, %d\n", util.FindMaxNumber(nsArgs))
		} else {
			for _, num := range nsArgs {
				if num == "all" {
					for _, pod := range podInfo {
						delPod(pod.Namespace, pod.Name, clientSet)
					}
					break
				}
				i, _ := strconv.Atoi(num)
				delPod(podInfo[i-1].Namespace, podInfo[i-1].Name, clientSet)
			}
		}

		wg.Done()
	}
}
